package org.newcih.web;

import org.newcih.pojo.Box;
import org.newcih.pojo.ResponseMessage;
import org.newcih.pojo.dto.FontSet;
import org.newcih.pojo.dto.TesseractObject;
import org.newcih.pojo.dto.TrainObject;
import org.newcih.train.TessTrainer;
import org.newcih.util.BoxUtils;
import org.newcih.util.FileUtils;
import org.newcih.util.ImageUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * 主工作Controler
 *
 * @author newcih
 * @version 2018-02-05
 */
@Controller
@RequestMapping(value = "/tesseract")
public class TesseractController {
    /**
     * 存放字体数据的路径
     */
    @Value("${TESS_DATA}")
    private String tessData;
    /**
     * 识别程序的bin路径
     */
    @Value("${TESS_HOME}")
    private String tessHome;
    /**
     * 工作目录
     */
    @Value("${INPUT_DATA_DIR}")
    private String inputDataDir;
    /**
     * 用户目录
     */
    private        String       homePath = System.getProperty("user.home");
    /**
     * 目前所有字体
     */
    private static List<String> fontList = new ArrayList<>();
    private static FontSet      fontSet  = new FontSet();

    /**
     * 识别接口
     *
     * @param tesseractObject 识别参数对象
     * @return
     */
    @RequestMapping(value = "distinguish")
    @ResponseBody
    public ResponseMessage distinguish(@RequestBody TesseractObject tesseractObject) throws Exception {
        // 将图片解码并序列化到本地
        String fileNameToSave = FileUtils.composePath(homePath, inputDataDir) + UUID.randomUUID();
        fileNameToSave = ImageUtils.decodeImage(tesseractObject.getImageStr(), fileNameToSave).getPath();
        String fontName = StringUtils.isEmpty(tesseractObject.getFontName()) ? "eng" : tesseractObject.getFontName();

        TessTrainer tessTrainer = new TessTrainer(tessHome, FileUtils.composePath(homePath, inputDataDir), fontName);
        // 判断字体是否存在
        if (!listFonts().getFontList().contains(fontName)) {
            return ResponseMessage.error(ResponseMessage.TESS_ERROR, "找不到该字体");
        }
        // 调用工作接口进行识别
        try {
            String result = tessTrainer.tesseract(fileNameToSave);
            return ResponseMessage.ok(ResponseMessage.TESS_OK, result);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseMessage.error(ResponseMessage.TESS_ERROR, "识别出错");
        }
    }

    /**
     * 训练接口
     *
     * @param trainObject 训练参数对象
     * @return
     */
    @RequestMapping(value = "train")
    @ResponseBody
    public ResponseMessage train(@RequestBody TrainObject trainObject) throws Exception {
        // 创建新的字体目录
        String newFontName = StringUtils.isEmpty(trainObject.getNewFontName())
                             ? UUID.randomUUID().toString()
                             : trainObject.getNewFontName();
        String fontFolderName    = FileUtils.composePath(homePath, inputDataDir, newFontName);
        File   newFontDataFolder = FileUtils.createFolder(fontFolderName);

        System.out.println("新的字体名" + newFontName);

        // 将图片解码并序列化到本地
        List<File> valueImageList = new ArrayList<>();
        for (String value : trainObject.getTrainData().keySet()) {
            String imageFileName = FileUtils.composePath(newFontDataFolder.getPath()) + "@" + value + "@";
            File   imageFile     = ImageUtils.decodeImage(trainObject.getTrainData().get(value), imageFileName);
            valueImageList.add(imageFile);
        }
        // 自定义生成box文件
        String tiffFileName          = FileUtils.composePath(newFontDataFolder.getPath()) + newFontName + ".tif";
        File   destMultiPageTiffFile = new File(tiffFileName);
        try {
            Box box = ImageUtils.mergeMultiTiff(valueImageList, destMultiPageTiffFile);
            BoxUtils.boxToFile(box, FileUtils.composePath(newFontDataFolder.getPath()) + newFontName + ".box");
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseMessage.error(ResponseMessage.TRAIN_ERROR, "自定义Box文件失败");
        }
        // 调用接口进行训练
        TessTrainer tessTrainer = new TessTrainer(tessHome, newFontDataFolder.getPath(), newFontName, tessData);
        // 如果待新增的字体名已存在，则更新
        File oldTrainedData = new File(FileUtils.composePath(tessData) + newFontName + ".traineddata");
        oldTrainedData.delete();

        try {
            tessTrainer.generateTraineddata();
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseMessage.error(ResponseMessage.TRAIN_ERROR, "训练字体失败");
        }

        return new ResponseMessage(ResponseMessage.TRAIN_OK,
                                   listFonts().getFontList().contains(newFontName) ? "更新字体数据成功" : "训练新字体成功",
                                   newFontName);
    }

    /**
     * 列出所有字体
     *
     * @return
     */
    @RequestMapping(value = "fonts")
    @ResponseBody
    public FontSet listFonts() throws Exception {
        TessTrainer tessTrainer = new TessTrainer(tessHome, homePath, null);
        fontList = tessTrainer.listFonts();
        fontSet.setFontList(fontList);
        return fontSet;
    }
}
